package Utilities;

import java.util.ArrayList;
import java.util.PriorityQueue;

import weka.core.Instances;

import data_structures.*;

/**
 * Helper functions for the application.
 */
public class Utils {

	/**
	 * Enumerate all possible configurations for the kNN classifier.
	 * 
	 * @param lowerBound
	 *            Lower-bound of k.
	 * @param upperBound
	 *            Upper-bound of k.
	 * @return All the configuration lowerBound <= k <= upperBound.
	 */
	public static ArrayList<HPConfiguration> enumerateConfigurationsForKNN(
			int lowerBound, int upperBound) {
		ArrayList<HPConfiguration> allConfs = new ArrayList<HPConfiguration>();

		for (int i = lowerBound; i <= upperBound; ++i) {
			HyperParameter k = new DiscreteHP(lowerBound, upperBound, i);
			HyperParameter[] hps = new HyperParameter[1];
			hps[0] = k;

			allConfs.add(new HPConfiguration(hps));
		}

		return allConfs;
	}

	/**
	 * Prints the priority queue
	 * 
	 * @param pairs
	 */
	public static void print(PriorityQueue<ConfigurationAccuracyPair> pairs) {
		while (pairs.size() > 0) {
			ConfigurationAccuracyPair pair = pairs.poll();
			System.out.println(pair.toString());
		}
	}

	/**
	 * Gets a portion of the data set.
	 * 
	 * @param instances
	 *            Entire data set.
	 * @param portion
	 *            Random portion (between 0 and 1) of the entire data set to be
	 *            returned
	 * @return
	 */
	public static Instances getInstancesPortion(Instances instances,
			double portion) {
		Instances resultInstances = new Instances(instances, 0, 0);

		int nInstances = (int) (instances.numInstances() * portion);

		for (int i = 0; i < nInstances; ++i) {
			int randomIndex = Constants.RANDOM
					.nextInt(instances.numInstances() - 1);
			resultInstances.add(instances.instance(randomIndex));
		}

		return resultInstances;
	}
}
